package com.AICoupon.utils;

import io.lettuce.core.RedisException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.data.redis.RedisSystemException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * Redis异常全局处理器
 * 处理Redis连接异常，提供重试机制
 */
@Slf4j
@Component
@RestControllerAdvice
public class RedisExceptionHandler {

    @Resource
    private RedisConnectionHealthChecker healthChecker;

    /**
     * 处理Redis系统异常
     */
    @ExceptionHandler(RedisSystemException.class)
    public Object handleRedisSystemException(RedisSystemException e) {
        log.error("Redis系统异常: {}", e.getMessage(), e);
        return handleRedisException(e);
    }

    /**
     * 处理Redis连接失败异常
     */
    @ExceptionHandler(RedisConnectionFailureException.class)
    public Object handleConnectionException(RedisConnectionFailureException e) {
        log.error("Redis连接失败: {}", e.getMessage(), e);
        return handleRedisException(e);
    }

    /**
     * 处理Lettuce Redis异常
     */
    @ExceptionHandler(RedisException.class)
    public Object handleLettuceRedisException(RedisException e) {
        log.error("Lettuce Redis异常: {}", e.getMessage(), e);
        return handleRedisException(e);
    }

    /**
     * 通用Redis异常处理逻辑
     */
    private Object handleRedisException(Exception e) {
        // 触发健康检查
        boolean isHealthy = healthChecker.checkConnectionManually();
        
        if (!isHealthy) {
            log.warn("Redis连接不健康，等待恢复...");
            // 等待一段时间，让健康检查器有机会恢复连接
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
            }
        }
        
        // 返回友好的错误信息
        return com.AICoupon.dto.Result.fail("系统繁忙，请稍后再试");
    }
}